package com.fellansoft.moviescollection.gui;

/**
 * Created by IntelliJ IDEA.
 * User: Edy
 * Date: 09.05.2012
 * Time: 00:03
 * To change this template use File | Settings | File Templates.
 */
import android.content.Context;
import android.graphics.*;
import android.graphics.Bitmap.Config;
import android.graphics.PorterDuff.Mode;
import android.graphics.Shader.TileMode;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import com.fellansoft.moviescollection.data.CoverFlowElement;
import com.fellansoft.moviescollection.gui.CoverFlow;

import java.util.List;

public class ImageAdapter extends BaseAdapter {
    /**
     * Backround image
     */
     int mGalleryItemBackground;
     /**
      * Current context
      */
     private Context mContext;
    /**
     * Gallery layout width
     */
     private int mLayoutWidth;
    /**
     * Gallery layout height
     */
     private int mLayoutHeight;
    /**
     * List containg the cover flow elements
     */
     private List<CoverFlowElement> mElements;

     public ImageAdapter(Context c, List<CoverFlowElement> coverFlowElements) {
      mContext = c;
      mLayoutHeight = 120;
      mLayoutWidth = 120;
      this.mElements = coverFlowElements;
     }

    public void setNewListOfElement(List<CoverFlowElement> coverFlowElements, boolean createReflections)
    {
        this.mElements = coverFlowElements;
        if (createReflections)
            this.createReflectedImages();
        this.notifyDataSetChanged();
    }

    public void setNewListOfElement(List<CoverFlowElement> coverFlowElements)
    {
        this.mElements = coverFlowElements;
        this.createReflectedImages();
        this.notifyDataSetChanged();
    }

     public void setLayoutParams(int width, int height)
     {
    	 mLayoutHeight = height;
    	 mLayoutWidth = width;
     }

    public void clearElements()
    {
        this.mElements.clear();
        this.notifyDataSetChanged();
    }

     public void addElement(CoverFlowElement elem, boolean notifyChange)
     {
         mElements.add(elem);
         createReflection(4,mElements.size()-1);
         if (notifyChange == true)
             this.notifyDataSetChanged();
     }

     private void createReflection(int reflectionGap, int i)
     {
        Bitmap originalImage = mElements.get(i).getBitmap();
        int width = originalImage.getWidth();
        int height = originalImage.getHeight();

        //This will not scale but will flip on the Y axis
        Matrix matrix = new Matrix();
        matrix.preScale(1, -1);

        //Create a Bitmap with the flip matrix applied to it.
        //We only want the bottom half of the image
        Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, 0/*height/2*/, width, height/*/2*/, matrix, false);



        //Create a new bitmap with same width but taller to fit reflection
        Bitmap bitmapWithReflection = Bitmap.createBitmap(width
            , (height + height /*/2*/), Config.ARGB_8888);

        //Create a new Canvas with the bitmap that's big enough for
        //the image plus gap plus reflection
        Canvas canvas = new Canvas(bitmapWithReflection);
        //Draw in the original image
        canvas.drawBitmap(originalImage, 0, 0, null);
        //Draw in the gap
        Paint deafaultPaint = new Paint();
        canvas.drawRect(0, height, width, height + reflectionGap, deafaultPaint);
        //Draw in the reflection
        canvas.drawBitmap(reflectionImage,0, height + reflectionGap, null);

        //Create a shader that is a linear gradient that covers the reflection
        Paint paint = new Paint();
        LinearGradient shader = new LinearGradient(0, originalImage.getHeight(), 0,
        bitmapWithReflection.getHeight() + reflectionGap - 50, 0x70ffffff, 0x00ffffff,
        TileMode.CLAMP);
        //Set the paint to use this shader (linear gradient)
        paint.setShader(shader);
        //Set the Transfer mode to be porter duff and destination in
        paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
        //Draw a rectangle using the paint with our linear gradient
        canvas.drawRect(0, height, width,
        bitmapWithReflection.getHeight() + reflectionGap, paint);

        /* ImageView imageView = new ImageView(mContext);
        imageView.setImageBitmap(bitmapWithReflection);
        imageView.setLayoutParams(new CoverFlow.LayoutParams(mLayoutWidth,(int)(1.5 * mLayoutHeight)));
        imageView.setScaleType(ScaleType.MATRIX);  */
        CoverFlowElement elem = mElements.get(i);
        elem.setBitmap(bitmapWithReflection);
        mElements.set(i,elem);

     }

  public boolean createReflectedImages() {
          //The gap we want between the reflection and the original image
          final int reflectionGap = 4;


          int index = 0;
          for (int i=0; i< mElements.size(); i++) {
            createReflection(reflectionGap,i);
          }
       return true;
  }

     public int getCount() {
         return mElements.size();
     }

     public Object getItem(int position) {
         return mElements.get(position);
     }

     public long getItemId(int position) {
         return position;
     }

     public View getView(int position, View convertView, ViewGroup parent) {

        ImageView imageView;
        if (convertView == null) {
            imageView = new ImageView(mContext);
            imageView.setLayoutParams(new CoverFlow.LayoutParams(mLayoutWidth, mLayoutHeight));
            imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
        } else
            imageView = (ImageView) convertView;
         //Make sure we set anti-aliasing otherwise we get jaggies
         imageView.setImageBitmap(mElements.get(position).getBitmap());
         //BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
         //drawable.setAntiAlias(true);
         return imageView;
     }
   /** Returns the size (0.0f to 1.0f) of the views
      * depending on the 'offset' to the center.
    * @return Scale
    * */
      public float getScale(boolean focused, int offset) {
        /* Formula: 1 / (2 ^ offset) */
          return Math.max(0, 1.0f / (float)Math.pow(2, Math.abs(offset)));
      }

 }